﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using NUnit.Framework;
using NUnit.Framework.Constraints;
using NUnit.Framework.SyntaxHelpers;
using Yaml.Presentation.Tokens;
using Yaml.Presentation.Parsing;

namespace Yaml.Tests.Presentation.ScannerTests {
    [TestFixture]
    public class DocumentStartAndEnd {
        [Test]
        public void SimpleDocumentStart() {
            Scanner s = Helper.CreateScanner("---");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentStartToken start={0:0,0} end={3:0,3}>"));
            t = s.GetToken();
            Assert.That(s.State.SimpleKeys.IsSimpleKeyAllowed, Is.False, "New document so there cannot be a simple key at this point.");
            Assert.That(s.State.Indentation.Current, Is.EqualTo(-1), "New document so the indentation has to be completely unwound.");
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={3:0,3} end={3:0,3}>"));
        }
        [Test]
        public void DocumentStartWithComments() {
            Scanner s = Helper.CreateScanner("  #Some comment\r\n---  # more comment   \n");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentStartToken start={17:1,0} end={20:1,3}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={40:2,0} end={40:2,0}>"));
        }
        [Test]
        public void DocumentStartWithDirectives() {
            Scanner s = Helper.CreateScanner("%YAML 1.1\n---");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<YamlDirectiveToken version='1.1' start={0:0,0} end={9:0,9}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentStartToken start={10:1,0} end={13:1,3}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={13:1,3} end={13:1,3}>"));
        }

        [Test]
        public void SimpleDocumentEnd() {
            Scanner s = Helper.CreateScanner("...");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentEndToken start={0:0,0} end={3:0,3}>"));
            Assert.That(s.State.SimpleKeys.IsSimpleKeyAllowed, Is.False, "New document so there cannot be a simple key at this point.");
            Assert.That(s.State.Indentation.Current, Is.EqualTo(-1), "New document so the indentation has to be completely unwound.");
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={3:0,3} end={3:0,3}>"));
        }

        [Test(Description="Remember that the subsequent comments are part of the DocumentEndToken")]
        public void DocumentEndWithComments() {
            Scanner s = Helper.CreateScanner("  #Some comment\r\n...  # more comment   \n");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentEndToken start={17:1,0} end={40:2,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={40:2,0} end={40:2,0}>"));
        }
        [Test]
        public void DocumentEndWithDirectives() {
            Scanner s = Helper.CreateScanner("%YAML 1.1\n...");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<YamlDirectiveToken version='1.1' start={0:0,0} end={9:0,9}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentEndToken start={10:1,0} end={13:1,3}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={13:1,3} end={13:1,3}>"));
        }

        [Test]
        public void DocumentStartAndEndWithDirectives() {
            Scanner s = Helper.CreateScanner("%YAML 1.1\n---\n...");
            Token t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamStartToken encoding='utf-8' start={0:0,0} end={0:0,0}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<YamlDirectiveToken version='1.1' start={0:0,0} end={9:0,9}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentStartToken start={10:1,0} end={13:1,3}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<DocumentEndToken start={14:2,0} end={17:2,3}>"));
            t = s.GetToken();
            Assert.That(t.ToString(), Is.EqualTo("#<StreamEndToken start={17:2,3} end={17:2,3}>"));
        }
    }
}
